package com.qinglian.netty;


import com.alibaba.fastjson.JSON;
import com.qinglian.utils.RedisUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.util.*;

@Configuration
@ChannelHandler.Sharable
public class CoordinationSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    @Autowired
    private RedisUtil redisUtil;

    public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    public Map<Integer, Channel> channelChannelMap = new HashMap<>();
    public Map<Channel, Integer> channelIntegerMap = new HashMap<>();

    public static Set<Channel> channelSet = Collections.synchronizedSet(new HashSet<>());


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("与客户端建立连接，通道开启！");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Integer userId = channelIntegerMap.get(ctx.channel());
        if (userId != null) {
            channelChannelMap.remove(userId);
            channelIntegerMap.remove(ctx.channel());
        }
        System.out.println("与客户端断开连接，通道关闭！");
        System.out.println("用户" + userId + "退出登录,当前在线人数为" + channelChannelMap.size());
        System.out.println("当前在线人数为" + channelChannelMap.size());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //接收的消息
        System.out.println(msg.text());
        Map map = JSON.parseObject(msg.text(), Map.class);
        String type = map.get("msgType").toString();
        switch (type) {
            case "600":   // 登录
                websocketLogin(map, ctx);
                break;
            case "601": // 退出登录
                unLogin(map);
                break;
            case "611": // 发送文字消息
            case "900":
            case "901":
            case "902":
            case "903":
            case "904":
            case "905":
                send(map);
                break;
        }
        System.out.println(String.format("收到客户端%s的数据：%s", ctx.channel().id(), msg.text()));
    }

    private void call(Map map) {
        Integer to = (Integer) map.get("toId");
        if (channelChannelMap.containsKey(to)) {
            Channel channel = channelChannelMap.get(to);
            channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(map)));
        } else {
            ArrayList<Map> records = new ArrayList<>();
            if (redisUtil.hasKey("record" + to)) {
                records = (ArrayList<Map>) redisUtil.get("record" + to);
                records.add(map);
            } else {
                records.add(map);
            }
            redisUtil.set("record" + to, records);
            System.out.println("未登录");

        }
    }

    private void websocketLogin(Map map, ChannelHandlerContext ctx) {
        Integer userId = (Integer) map.get("userId");
        channelChannelMap.put(userId, ctx.channel());
        channelIntegerMap.put(ctx.channel(), userId);
        System.out.println("用户" + userId + "登录,当前在线人数为" + channelChannelMap.size());
        if (redisUtil.hasKey("record" + userId)) {
            ArrayList<Map> records = (ArrayList<Map>) redisUtil.get("record" + userId);
            for (Map record : records) {
                Channel channel = channelChannelMap.get(userId);
                channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(record)));
                System.out.println(record.toString());
            }
            redisUtil.delKey("record" + userId);
        }
    }

    private void unLogin(Map map) {
        Integer id = (Integer) map.get("userId");
        Channel channel = channelChannelMap.get(id);
        if (channel != null) {
            channelChannelMap.remove(id);
            channelIntegerMap.remove(channel);
        }
        System.out.println("用户" + id + "退出登录,当前在线人数为" + channelChannelMap.size());
    }

    private void send(Map map) {
        Integer to = (Integer) map.get("toId");
        if (channelChannelMap.containsKey(to)) {
            Channel channel = channelChannelMap.get(to);
            channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(map)));
        } else {
            ArrayList<Map> records = new ArrayList<>();
            if (redisUtil.hasKey("record" + to)) {
                records = (ArrayList<Map>) redisUtil.get("record" + to);
                records.add(map);
            } else {
                records.add(map);
            }
            redisUtil.set("record" + to, records);
            System.out.println("未登录");

        }
    }
}
